package ca;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;

import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Chart extends JPanel
{
	public JFrame frame;
	public ArrayList<ArrayList<Integer>> graphData;
	
	public final Color[] colours = {Color.RED, Color.BLUE, Color.BLACK, Color.CYAN, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.YELLOW};

	public int width;
	public int height;

	public Graphics2D g2d;

	private int pad = 20;

	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);

		g2d =  (Graphics2D)g;

		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

		width = getWidth();
		height = getHeight();

		g2d.draw(new Line2D.Double(pad, pad, pad, height - pad));
		g2d.draw(new Line2D.Double(pad, height - pad, width - pad, height - pad));

		Font font = g2d.getFont();

		FontRenderContext fRendCont = g2d.getFontRenderContext();

		LineMetrics lineMet = font.getLineMetrics("0", fRendCont);

		float sh = lineMet.getAscent() + lineMet.getDescent();

		String yLabel = "Population Size";

		float sy = pad + ((height - 2*pad) - yLabel.length()*sh) / 2 + lineMet.getAscent();

		for(int i = 0; i < yLabel.length(); i++, sy += sh)
		{
			String letter = String.valueOf(yLabel.charAt(i));
			float sw = (float)font.getStringBounds(letter, fRendCont).getWidth();
			float sx = (pad - sw) / 2;

			g2d.drawString(letter, sx, sy);
		}

		String xLabel = "No. of Steps";

		sy = height - pad + (pad - sh) / 2 + lineMet.getAscent();

		float sw = (float)font.getStringBounds(xLabel, fRendCont).getWidth();
		float sx = (width - sw) / 2;

		g2d.drawString(xLabel, sx, sy);

		for(int i = 0; i < graphData.size(); i++)
		{
			drawLines(graphData.get(i), i);
		}
	}

	public void drawLines(ArrayList<Integer> data, int colorIndex)
	{
		double xInc = (double)(width - 2*pad) / (data.size() - 1);
		double scale = (double)(height - 2*pad) / getMax();

		g2d.setPaint(colours[colorIndex]);
		for(int i = 0; i < data.size() - 1; i++)
		{
			double x1 = pad + (i * xInc);
			double y1 = height - pad - (scale * data.get(i));
			double x2 = pad + ((i + 1) * xInc);
			double y2 = height - pad - (scale * data.get(i + 1));

			g2d.draw(new Line2D.Double(x1, y1, x2, y2));
		}

		g2d.setPaint(colours[colorIndex]);
		for(int i = 0; i < data.size(); i++)
		{
			double x = pad + (i * xInc);
			double y = height - pad - (scale * data.get(i));


			g2d.fill(new Ellipse2D.Double(x - 2, y - 2, 4, 4));
		}

	}

	public int getMax()
	{
		int max = -Integer.MAX_VALUE;

		for(int j = 0; j < graphData.size(); j++)
		{
			for(int i = 0; i < graphData.get(j).size(); i++)
			{
				if(graphData.get(j).get(i) > max)
				{
					max = graphData.get(j).get(i);
				}
			}
		}
		return max;
	}
	
	public void updatePopulations(int[] populations)
	{
		for(int i = 0; i < populations.length; i++)
		{
			graphData.get(i).add(populations[i]);
		}
		frame.repaint();
	}

	public Chart(int[] population)
	{
		frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(this);
		frame.setSize(400,400);
		frame.setLocation(200,200);
		frame.setVisible(true);
		frame.repaint();
		graphData = new ArrayList<ArrayList<Integer>>(population.length);
		for(int i = 0; i < population.length; i++)
		{
			graphData.add(new ArrayList<Integer>());
			graphData.get(i).add(population[i]);
		}

		frame.repaint();

	}


}
